package org.as3search.criteria {
	/*
	 * as3search - http://code.google.com/p/as3search
	 * Copyright (c) 2009-2010 by respective authors. All rights reserved.
	 *
	 * This library is free software; you can redistribute it and/or modify it under the
	 * terms of the GNU Lesser General Public License as published by the Free Software
	 * Foundation; either version 2.1 of the License, or (at your option) any later
	 * version.
	 *
	 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
	 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
	 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
	 *
	 * You should have received a copy of the GNU Lesser General Public License along
	 * with this library; if not, write to the Free Software Foundation, Inc.,
	 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
	 */
	
	/**
	 * <code>Restrictions</code> is a static factory for quickly
	 * and easily creating <code>Criterion</code> instances. All
	 * expressions included with as3search are implemented here
	 * with factory methods.
	 * 
	 * @example The <code>Restrictions</code> class makes it easy to 
	 * create <code>Criterion</code> instances for searching through a
	 * collection:
	 * <listing version="1.0">
	 * Search.within(myCollection)
	 * 	.add(Restrictions.eq("id", 1)) //id must equal 1
	 * 	.add(Restrictions.ne("name", "nancy")) //name must not be "nancy"
	 * 	.add(Restrictions.gt("age", 30)) //age must be greater than 30
	 * </listing>
	 */
	public class Restrictions {
		/**
		 * Creates an "equals-to" <code>Criterion</code> between <code>propertyName</code>
		 * and <code>value</code>.
		 * @param	propertyName	The name of the property to evaluate as equal to <code>value</code>.
		 * @param	value			The value to be compared to the value of <code>propertyName</code>.
		 * @param	ignoreCase		For String values, whether to ignore capitalization.
		 * @return	Returns a new <code>EqualityExpression</code> ready to use with 
		 * 		a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.EqualityExpression
		 */
		public static function eq(propertyName:String, value:Object, 
				ignoreCase:Boolean = false):Criterion {
			return new EqualityExpression(propertyName, value, null, ignoreCase);
		}
		/**
		 * Creates a "not-equal-to" <code>Criterion</code> between <code>propertyName</code>
		 * and <code>value</code>.
		 * @param	propertyName	The name of the property to evaluate as not equal to <code>value</code>.
		 * @param	value			The value to be compared to the value of <code>propertyName</code>.
		 * @param	ignoreCase		For String values, whether to ignore capitalization.
		 * @return	Returns a new <code>NotEqualsExpression</code> ready to use with 
		 * 		a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.NotEqualsExpression
		 */
		public static function ne(propertyName:String, value:Object,
				ignoreCase:Boolean = false):Criterion {
			return new NotEqualsExpression(propertyName, value, null, ignoreCase);
		}
		/**
		 * Creates a "greater-than" <code>Criterion</code> between <code>propertyName</code>
		 * and <code>value</code>.
		 * @param	propertyName	The name of the property to evaluate as greater than <code>value</code>.
		 * @param	value			The value to be compared to the value of <code>propertyName</code>.
		 * @param	ignoreCase		For String values, whether to ignore capitalization.
		 * @return 	Returns a new <code>GreaterThanExpression</code> ready for use with
		 * 		a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.GreaterThanExpression
		 */
		public static function gt(propertyName:String, value:Object,
				ignoreCase:Boolean = false):Criterion {
			return new GreaterThanExpression(propertyName, value, null, ignoreCase);
		}
		/**
		 * Creates a "greater-than-or-equals" <code>Criterion</code> between <code>propertyName</code>
		 * and <code>value</code>.
		 * @param	propertyName	The name of the property to evaluate as greater than or equal to <code>value</code>.
		 * @param	value			The value to be compared to the value of <code>propertyName</code>.
		 * @param	ignoreCase		For String values, whether to ignore capitalization.
		 * @return	Returns a new <code>GreaterThanOrEqualsExpression</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.GreaterThanOrEqualsExpression
		 */
		public static function ge(propertyName:String, value:Object,
				ignoreCase:Boolean = false):Criterion {
			return new GreaterThanOrEqualsExpression(propertyName, value, null, ignoreCase);
		}
		/**
		 * Creates a "less-than" <code>Criterion</code> between <code>propertyName</code>
		 * and <code>value</code>.
		 * @param	propertyName	The name of the property to evaluate as less than <code>value</code>.
		 * @param	value			The value to be compared to the value of <code>propertyName</code>.
		 * @param	ignoreCase		For String values, whether to ignore capitalization.
		 * @return 	Returns a new <code>LessThanExpression</code> ready for use 
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.LessThanExpression
		 */
		public static function lt(propertyName:String, value:Object,
				ignoreCase:Boolean = false):Criterion {
			return new LessThanExpression(propertyName, value, null, ignoreCase);
		}
		/**
		 * Creates a "less-than-or-equals-to" <code>Criterion</code> between <code>
		 * propertyName</code> and <code>value</code>.
		 * @param	propertyName	The name of the property to evaluate as less than or equal to <code>value</code>.
		 * @param	value			The value to be compared to the value of <code>propertyName</code>.
		 * @param	ignoreCase		For String values, whether to ignore capitalization.
		 * @return	Returns a new <code>LessThanOrEqualsExpression</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.LessThanOrEqualsExpression
		 */
		public static function le(propertyName:String, value:Object,
				ignoreCase:Boolean = false):Criterion {
			return new LessThanOrEqualsExpression(propertyName, value, null, ignoreCase);
		}
		/**
		 * Creates a regular expression <code>Criterion</code> between <code>propertyName</code>
		 * and <code>value</code>. 
		 * @param	propertyName	The name of the property to match against <code>value</code>.
		 * @param	value			The regular expression to evaluate against the value of <code>propertyName</code>.
		 * @return	Returns a new <code>RegExpExpression</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.RegExpExpression
		 */
		public static function matches(propertyName:String, value:RegExp):Criterion {
			return new RegExpExpression(propertyName, value, null, false);
		}
		/**
		 * Creates an "is-null" <code>Criterion</code> targeting <code>propertyName</code>.
		 * @param	propertyName	The name of the property to validate as null.
		 * @return 	Returns a new <code>NullExpression</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.NullExpression
		 */
		public static function isNull(propertyName:String):Criterion {
			return new NullExpression(propertyName);
		}
		/**
		 * Creates a "not-null" <code>Criterion</code> targeting <code>propertyName</code>.
		 * @param 	propertyName	The name of the property to validate as not null.
		 * @return 	Returns a new <code>NotNullExpression</code> ready for use 
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.NotNullExpression 
		 */
		public static function isNotNull(propertyName:String):Criterion {
			return new NotNullExpression(propertyName);
		}
		/**
		 * Creates an "is-empty" <code>Criterion</code> targeting <code>propertyName</code>.
		 * @param	propertyName	The name of the property to evaluate as being empty.
		 * @return	Returns a new <code>EmptyExpression</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.EmptyExpression
		 */
		public static function isEmpty(propertyName:String):Criterion {
			return new EmptyExpression(propertyName);
		}
		/**
		 * Creates an "is-not-empty" <code>Criterion</code> targeting <code>propertyName</code>.
		 * @param	propertyName	The name of the property to evaluate as being not empty.
		 * @return	Returns a new <code>NotEmptyExpression</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.NotEmptyExpression
		 */
		public static function isNotEmpty(propertyName:String):Criterion {
			return new NotEmptyExpression(propertyName);
		}
		/**
		 * Creates a negative <code>Criterion</code> based on <code>expression</code>.
		 * @param	expression		The <code>Criterion</code> to test the inverse of.
		 * @return	Returns a new <code>NotExpression</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.NotExpression
		 */
		public static function not(expression:Criterion):Criterion {
			return new NotExpression(expression);
		}
		/**
		 * Creates a new conjunction for testing that multiple conditions are met.
		 * @return	Returns a new <code>Conjunction</code> ready for use 
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.Conjunction
		 */
		public static function conjunction():Junction {
			return new Conjunction();
		}
		/**
		 * Creates a new disjunction for testing that at least one of multiple conditions
		 * are met.
		 * @return	Returns a new <code>Disjunction</code> ready for use
		 * 		with a <code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.Disjunction
		 */
		public static function disjunction():Junction {
			return new Disjunction();
		}
		/**
		 * Creates a new "is-greater-than-and-less-than" <code>Criterion</code> targeting
		 * <code>propertyName</code>.
		 * @param	propertyName	The name of the property to evaluate as greater than
		 * 		<code>lowValue</code> and less than <code>highValue</code>.
		 * @param	lowValue		The low value of what <code>propertyName</code> must be
		 * 		greater than.
		 * @param	highValue		The high value of what <code>propertyName</code> must be
		 * 		less than.
		 * @return	Returns a new <code>Criterion</code> instance ready for use with a 
		 * 		<code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.GreaterThanExpression
		 * @see org.as3search.criteria.LessThanExpression
		 */
		public static function between(propertyName:String, lowValue:Object, highValue:Object):Criterion {
			var conj:Junction = new Conjunction();
			conj.add(new GreaterThanExpression(propertyName, lowValue))
				.add(new LessThanExpression(propertyName, highValue));
			return conj;
		}
		/**
		 * Creates a new "and" <code>Criterion</code> of <code>value1</code> and 
		 * <code>value2</code>.
		 * @param	value1	The first condition to be met.
		 * @param	value2	The second condition to be met.
		 * @return	Returns a new <code>Conjunction</code> instance ready for use with a 
		 * 		<code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.Conjunction
		 */
		public static function and(value1:Criterion, value2:Criterion):Junction {
			var conj:Junction = new Conjunction();
			conj.add(value1).add(value2);
			return conj;
		}
		/**
		 * Creates a new "or" <code>Criterion</code> of <code>value1</code> and
		 * <code>value2</code>.
		 * @param	value1	The first condition to be met.
		 * @param	value2	The second condition to be met.
		 * @return	Returns a new <code>Disjunction</code> instance ready for use with a 
		 * 		<code>Criteria</code> instance.
		 * 
		 * @see org.as3search.criteria.Disjunction
		 */
		public static function or(value1:Criterion, value2:Criterion):Junction { 
			var conj:Junction = new Disjunction();
			conj.add(value1).add(value2);
			return conj;
		}
	}
}